﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Identity;
using Ornament.ImportHelper;
using Text.Helper;

namespace Fee.IO.Importers
{
    internal static class ImportHelper
    {
        public static T ImportEnum<T>(this IList<string> data, int post, string column, ImportResultItem item,
            bool isRequire) where T : struct
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return default(T);
            }

            var success = EnumHelper.TryFromDisplayName(data[post], out T type);
            if (!success)
            {
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别。");
                return default(T);
            }

            return type;
        }

        public static decimal ImportDecimal(this IList<string> data, int post, string column, ImportResultItem item,
            bool isRequire)
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return 0;
            }

            var success = decimal.TryParse(data[post], out var result);
            if (!success)
            {
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别为数值型。");
                return default(decimal);
            }

            return result;
        }

        public static decimal ImportPrecent(this IList<string> data, int post, string column, ImportResultItem item,
            bool isRequire)
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return 0;
            }

            var val = data[post].Contains("%") ? data[post].Replace("%", "") : data[post];
            var success = decimal.TryParse(val, out var result);
            if (!success)
            {
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别为数值型。");
                return default(decimal);
            }

            return result;
        }


        public static int ImportInt(this IList<string> data, int post, string column, ImportResultItem item,
            bool isRequire = true)
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return 0;
            }

            var success = int.TryParse(data[post], out var result);
            if (!success)
            {
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别为数值型。");
                return default(int);
            }

            return result;
        }

        public static string ImportString(this IList<string> data, int post, string column, ImportResultItem item,
            bool isRequire = true)
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return "";
            }

            var success = !string.IsNullOrEmpty(data[post]);
            if (!success)
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别。");
            return data[post].Trim();
        }

        public static DateTimeOffset ImportDatetime(this IList<string> data, int post, string column,
            ImportResultItem item,
            bool isRequire = true)
        {
            if (data.Count <= post || string.IsNullOrEmpty(data[post]))
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return DateTimeOffset.MinValue;
            }


            var success = DateTimeOffset.TryParseExact(data[post], "yyyy-MM-dd", null, DateTimeStyles.None,
                out var dateTime);
            if (!success)
                item.AddError(post, column + "不正确，输入'" + data[post] + "'无法识别 请输入 2019-01-23 这样的格式。");
            return dateTime;
        }

        public static DateTimeOffset? ImportDatetimeNullable(this IList<string> data, int post, string column,
            ImportResultItem item,
            bool isRequire = true)
        {
            var result = ImportDatetime(data, post, column, item, isRequire);
            if (result == DateTimeOffset.MinValue)
                return null;
            return result;
        }

        public static Vendor ImportVendor(this IList<string> data, int post, string column, ImportResultItem item,
            FeeDbContext context,
            bool isRequire = true)
        {
            if (data.Count <= post)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var nameOfUnit = data[post];
            if (string.IsNullOrEmpty(nameOfUnit) && isRequire)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var vendor = context.Vendors.FirstOrDefault(f => f.Name == nameOfUnit);
            if (vendor == null)
            {
                vendor = new Vendor
                {
                    FullName = nameOfUnit,
                    Name = nameOfUnit
                };

                context.Add(vendor);
                context.SaveChanges();
            }

            return vendor;
        }

        public static FrameworkContract ImportFrameworkContract(this IList<string> data, int post, string column,
            ImportResultItem item, FeeDbContext context, bool isRequire = true)
        {
            if (data.Count <= post)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var nameOfUnit = data[post];
            if (string.IsNullOrEmpty(nameOfUnit) && isRequire)
            {
                item.AddError(post, column + "是必须有值");
                return null;
            }

            var fw = context.FrameworkContracts.FirstOrDefault(f => f.No == nameOfUnit);
            if (fw == null)
                if (isRequire)
                    item.AddError(post, column + "找不到对应的框架合同");

            return fw;
        }

        public static Vendor ImportVendorByFullName(this IList<string> data, int post, string column,
            ImportResultItem item,
            FeeDbContext context,
            bool isRequire = true)
        {
            if (data.Count <= post)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var nameOfUnit = data[post];
            if (string.IsNullOrEmpty(nameOfUnit) && isRequire)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var vendor = context.Vendors.FirstOrDefault(f => f.FullName == nameOfUnit);
            if (vendor == null)
            {
                vendor = new Vendor
                {
                    FullName = nameOfUnit,
                    Name = nameOfUnit
                };

                context.Add(vendor);
                context.SaveChanges();
            }

            return vendor;
        }

        public static Project ImportProject(this IList<string> data, int post, string column,
            ImportResultItem item, FeeDbContext context, bool isRequire = true)
        {
            if (data.Count <= post)
            {
                if (isRequire)
                    item.AddError(post, column + "是必须有值");
                return null;
            }

            var nameOfUnit = data[post];
            if (string.IsNullOrEmpty(nameOfUnit) && isRequire)
            {
                item.AddError(post, column + "是必须有值");
                return null;
            }

            var fw = context.Projects.FirstOrDefault(f => f.No == nameOfUnit);
            if (fw == null)
            {
                var mappingCode = context.Set<ProjectNumberMapping>().FirstOrDefault(f => f.ShortNo == nameOfUnit)?.No;
                fw = context.Projects.FirstOrDefault(f => f.No == mappingCode);
                if (fw == null && isRequire)
                    item.AddError(post, column + "通过" + nameOfUnit + " 没有找到相关的项目");
            }

            return fw;
        }
    }
}